package com.cms.jy.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionRequest;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 歌词分镜处理工具类
 */
@Slf4j
public class LyricFenjingUtil {
    // 从环境变量中获取您的 API Key。此为默认方式，您可根据需要进行修改
    private static final String API_KEY = "e36b0d2d-c53b-42ab-a76f-2bac43a44b25";
    // 此为默认路径，您可根据业务所在地域进行配置
    private static final String BASE_URL = "https://ark.cn-beijing.volces.com/api/v3";
    private static ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
    private static Dispatcher dispatcher = new Dispatcher();
    private static ArkService service = ArkService.builder()
            .dispatcher(dispatcher)
            .connectionPool(connectionPool)
            .baseUrl(BASE_URL)
            .apiKey(API_KEY)
            .build();

    /**
     * 根据SRT内容生成分镜数据
     *
     * @param srtContent SRT字幕内容
     * @return 分镜数据JSONArray
     */
    public static JSONArray generateFenjing(String srtContent) {
        try {
            log.info("开始生成歌词分镜数据");

            final List<ChatMessage> messages = new ArrayList<>();
            // 指令模板：明确任务目标+输出格式（参考前文指令模板）
            String systemPrompt = "你作为专业分镜创作师，需基于提供的文案字幕 SRT 文件设计分镜，核心遵循 “单个分镜时长≥5 秒 + 单分镜仅 1 个核心地点” 原则，通过合并短时长且逻辑连贯的 SRT 条目（单条 / 多条时长 < 5 秒）形成符合要求的分镜，同时关键字严格按 “地点词，人物数量描述词，核心动作 / 状态词，细节词” 顺序排列，具体要求如下：\u200B\n" +
                    "1. 分镜合并与地点规则\u200B\n" +
                    "时长要求：优先筛选 SRT 中 “单条时长 < 5 秒” 的条目，与相邻、同一场景（仅 1 个核心地点） 、情感一致的短时长条目合并，确保合并后分镜时长≥5 秒（建议 5-8 秒，避免过长逻辑断裂）；单条时长≥5 秒且场景唯一的条目，直接作为独立分镜。\u200B\n" +
                    "地点唯一性：每个分镜仅选 1 个 “核心地点词”（从词库选基础地点：房子、马路、街道、高楼等），禁止跨场景合并（如 “房子内记话题” 与 “街道送朋友” 不可合并，需拆分或聚焦单一地点；若文本含场景过渡，优先选 “主要情节发生地”，如 “送朋友后回房子” 优先选 “房子”）。\u200B\n" +
                    "情感连贯性：合并条目需情感一致（如均为孤独、均为平静），禁止 “热闹（群体）” 与 “孤独（单人）”“室内冷清” 与 “室外落寞” 等跨情感合并。\u200B\n" +
                    "2. 关键字设计与顺序要求\u200B\n" +
                    "关键字从指定词库选取，含 4 个独立元素，全程以英文逗号分隔，固定顺序为 “地点词，人物数量描述词，核心动作 / 状态词，细节词”，禁止冲突或无关元素：\u200B\n" +
                    "地点词：仅 1 个核心基础地点（如房子、街道、高楼），不出现多个地点并列（如禁止 “房子，街道”），需匹配分镜核心场景。\u200B\n" +
                    "人物数量描述词：按合并文本逻辑选 “一个人”“两个人”“一群人”“无人”，若有合理过渡（如 “两个人送别→一个人留驻”），可标注过渡状态（如 “两个人，一个人”），但需与核心地点适配。\u200B\n" +
                    "核心动作 / 状态词：提炼合并条目的 “连贯逻辑行为或核心情绪”，需与核心地点强关联（如核心地点为 “房子”，动作不可为 “马路看车流”；核心地点为 “街道”，动作不可为 “厨房煮面”），避免冲突（如禁止 “记话题送朋友” 这类跨地点动作，需调整为 “记话题后送别” 且聚焦单一地点）。\u200B\n" +
                    "细节词：仅标注与核心地点相关的 “区域特征或道具”，数量 1-3 个（用英文逗号分隔），需与核心地点、核心动作匹配（如核心地点为 “房子”，细节词可 “书房区域，笔记本”；核心地点为 “街道”，细节词可 “餐厅门口，挥手动作”），禁止无关细节（如核心地点为 “房子”，不可加 “傍晚马路”）。\u200B\n" +
                    "示例：合并 “房子内记话题→房子内整理送别物品”（核心地点 “房子”）→ keywords“房子，一个人，记话题后整理送别物，书房区域，笔记本”；合并 “街道送别朋友→街道独自留驻”（核心地点 “街道”）→ keywords“街道，两个人，一个人，送别后独自留驻，餐厅门口，挥手动作”。\u200B\n" +
                    "3. 元素匹配标准\u200B\n" +
                    "地点词：唯一且对应分镜核心场景，不跨场景。\u200B\n" +
                    "人物数量描述词：与核心地点、文本逻辑适配，无矛盾（如核心地点 “高楼（办公室）”，人数可为 “一群人”；核心地点 “房子（卧室）”，人数多为 “一个人”）。\u200B\n" +
                    "核心动作 / 状态词：不跨地点、不冲突，能串联合并条目逻辑（如合并 “房子内翻合照→房子内陷失落”，动作 / 状态词 “翻合照后陷失落”）。\u200B\n" +
                    "细节词：仅服务于核心地点与核心动作，无无关或冲突元素。\u200B\n" +
                    "4. 输出格式规则\u200B\n" +
                    "严格采用 Json 格式，keywords 字段内所有元素以英文逗号分隔，禁止出现 “衔接”“条目 X-Y” 等标注，禁止中文逗号，禁止多地点并列、跨地点动作、无关细节。\u200B\n" +
                    "start 为合并条目的 “首个条目 start 时间戳”，end 为合并条目的 “最后 1 个条目 end 时间戳”（格式：00:00:00,000）。\u200B\n" +
                    "Json 结构示例：{\"fenjins\":[{\"keywords\":\"地点词，人物数量描述词，核心动作 / 状态词，细节词 1, 细节词 2\",\"start\":\"合并后 start\",\"end\":\"合并后 end\"}]}\u200B\n" +
                    "5. 校验标准\u200B\n" +
                    "输出后需自查六点：①所有分镜时长≥5 秒；②单分镜仅 1 个核心地点，无跨场景；③合并条目情感连贯；④keywords 按 “地点词，人物数量描述词，核心动作 / 状态词，细节词” 顺序排列，无冲突；⑤所有元素以英文逗号分隔；⑥同一 SRT 条目不重复合并。\u200B\n";

            final ChatMessage systemMessage = ChatMessage.builder()
                    .role(ChatMessageRole.SYSTEM)
                    .content(systemPrompt)
                    .build();
            final ChatMessage userMessage = ChatMessage.builder()
                    .role(ChatMessageRole.USER)
                    .content("输入的歌曲SRT如下：" + srtContent)
                    .build();
            messages.add(systemMessage);
            messages.add(userMessage);

            ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
                    // 指定您创建的方舟推理接入点 ID，此处已帮您修改为您的推理接入点 ID
                    .model("doubao-1-5-pro-256k-250115")
                    .messages(messages)
                    .build();

            StringBuilder result = new StringBuilder();
            service.createChatCompletion(chatCompletionRequest).getChoices().forEach(choice -> {
                log.info("AI返回内容: {}", choice.getMessage().getContent());
                result.append(choice.getMessage().getContent());
            });

            // 解析返回的JSON数据
            JSONObject jsonObject = JSON.parseObject(result.toString());
            JSONArray fenjins = jsonObject.getJSONArray("fenjins");

            log.info("成功生成分镜数据，共{}个分镜", fenjins.size());
            return fenjins;

        } catch (Exception e) {
            log.error("生成分镜数据失败", e);
            throw new RuntimeException("生成分镜数据失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理分镜数据
     *
     * @param fenjins 分镜数据
     */
    public static List<JSONObject> processFenjins(JSONArray fenjins) {
        List<JSONObject> fenjinList = new ArrayList<>();
        try {
            log.info("开始处理分镜数据");

            fenjins.stream().iterator().forEachRemaining(item -> {
                try {
                    log.info("处理分镜项: {}", item);
                    JSONObject fenjinItem = (JSONObject) item;

                    // 根据实际返回的数据结构进行处理
                    // 这里需要根据AI实际返回的数据结构调整
                    String keywords = fenjinItem.getString("keywords");
                    String start = fenjinItem.getString("start");
                    String end = fenjinItem.getString("end");
                    log.info("分镜关键字: {}, 开始时间: {}, 结束时间: {}", keywords, start, end);
                    fenjinList.add(fenjinItem);
                } catch (Exception e) {
                    log.error("处理单个分镜项失败", e);
                }
            });

            log.info("分镜数据处理完成");
        } catch (Exception e) {
            log.error("处理分镜数据失败", e);
            throw new RuntimeException("处理分镜数据失败: " + e.getMessage(), e);
        }
        return fenjinList;
    }

    /**
     * 关闭服务连接
     */
    public static void shutdown() {
        try {
            if (service != null) {
                service.shutdownExecutor();
            }
            log.info("分镜服务已关闭");
        } catch (Exception e) {
            log.error("关闭分镜服务失败", e);
        }
    }

    /**
     * 示例调用方法
     */
    public static void main(String[] args) throws IOException {
        String srtContent = new String(Files.readAllBytes(Paths.get("E:\\自媒体\\生成\\45c57cfd-2921-4965-9eec-7978e1921508\\1.srt")), StandardCharsets.UTF_8);
        try {
            // 生成分镜数据
            JSONArray fenjins = generateFenjing(srtContent);
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writerWithDefaultPrettyPrinter()
                    .writeValueAsString(fenjins);
            System.out.println(json);
            // 处理分镜数据
            processFenjins(fenjins);

        } catch (Exception e) {
            log.error("处理失败", e);
        } finally {
            // 关闭服务
            shutdown();
        }
    }
}
